package com.mqtt.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mqtt.service.MqttService;
import com.mqtt.service.impl.DeviceSessionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MQTT命令消息监听器
 * 专门监听API服务发送给MQTT服务的命令
 */
@Slf4j
@Component
public class MqttCommandListener {
    
    @Autowired
    private MqttService mqttService;
    
    @Autowired
    private DeviceSessionService deviceSessionService;
    
    /**
     * 监听API服务发送的MQTT命令
     */
    @KafkaListener(
        topics = "${kafka.consumer.topics.mqtt-command}",
        groupId = "${kafka.consumer.group.id}",
        containerFactory = "kafkaListenerContainerFactory"
    )
    public void handleMqttCommand(List<ConsumerRecord<String, String>> records, Acknowledgment ack) {
        try {
            for (ConsumerRecord<String, String> record : records) {
                String imei = record.key();
                String value = record.value()
                    .replace("\r", "")
                    .replace("\n", "")
                    .replace("\ufeff", "");
                
                log.info("Received MQTT command - topic: {}, imei: {}, value: {}", 
                        record.topic(), imei, value);
                
                try {
                    JSONObject message = JSON.parseObject(value);
                    if (message != null && imei != null && !imei.isEmpty()) {
                        processCommand(imei, message);
                    }
                } catch (Exception e) {
                    log.error("Error parsing message for device: {}, error: {}", imei, e.getMessage());
                }
            }
            
            // 确认消息
            ack.acknowledge();
            
        } catch (Exception e) {
            log.error("Error processing MQTT commands", e);
        }
    }
    
    /**
     * 处理命令
     */
    private void processCommand(String imei, JSONObject message) {
        String command = message.getString("command");
        JSONObject data = message.getJSONObject("data");
        
        log.info("Processing command for device: {}, command: {}", imei, command);
        
        // 根据命令类型处理
        switch (command) {
            case "send_message":
                handleSendMessage(imei, data);
                break;
            case "send_command":
                handleSendCommand(imei, data);
                break;
            case "config_update":
                handleConfigUpdate(imei, data);
                break;
            case "ota_update":
                handleOtaUpdate(imei, data);
                break;
            case "location_request":
                handleLocationRequest(imei, data);
                break;
            case "device_control":
                handleDeviceControl(imei, data);
                break;
            case "batch_command":
                handleBatchCommand(imei, data);
                break;
            default:
                handleGenericCommand(imei, command, data);
        }
    }
    
    /**
     * 处理发送消息
     */
    private void handleSendMessage(String imei, JSONObject data) {
        try {
            // 检查设备是否在线
            if (!deviceSessionService.isDeviceOnline(imei)) {
                log.warn("Device {} is offline, message will be cached", imei);
                cacheOfflineMessage(imei, data);
                return;
            }
            
            // 构建MQTT消息
            Map<String, Object> mqttMessage = new HashMap<>();
            mqttMessage.put("type", "message");
            mqttMessage.put("content", data.getString("content"));
            mqttMessage.put("msgId", data.getString("msgId"));
            mqttMessage.put("timestamp", System.currentTimeMillis());
            
            // 发送到设备
            String topic = "device/" + imei + "/message";
            boolean sent = mqttService.sendToTopic(topic, JSON.toJSONString(mqttMessage));
            
            if (sent) {
                log.info("Message sent to device: {}", imei);
                // 可以发送确认消息回API服务
                sendAckToApi(imei, data.getString("msgId"), true, "Message sent");
            } else {
                log.error("Failed to send message to device: {}", imei);
                sendAckToApi(imei, data.getString("msgId"), false, "Send failed");
            }
            
        } catch (Exception e) {
            log.error("Error handling send message for device: {}", imei, e);
        }
    }
    
    /**
     * 处理发送命令
     */
    private void handleSendCommand(String imei, JSONObject data) {
        try {
            String cmd = data.getString("cmd");
            JSONObject params = data.getJSONObject("params");
            
            Map<String, Object> commandData = new HashMap<>();
            commandData.put("cmd", cmd);
            commandData.put("params", params);
            commandData.put("cmdId", data.getString("cmdId"));
            commandData.put("timestamp", System.currentTimeMillis());
            
            // 使用QoS 2确保命令送达
            String topic = "device/" + imei + "/command";
            boolean sent = mqttService.sendToTopic(topic, JSON.toJSONString(commandData), 2, false);
            
            log.info("Command {} {} to device: {}", cmd, sent ? "sent" : "failed", imei);
            
        } catch (Exception e) {
            log.error("Error handling send command for device: {}", imei, e);
        }
    }
    
    /**
     * 处理配置更新
     */
    private void handleConfigUpdate(String imei, JSONObject data) {
        try {
            Map<String, Object> configMessage = new HashMap<>();
            configMessage.put("type", "config_update");
            configMessage.put("config", data.getJSONObject("config"));
            configMessage.put("version", data.getString("version"));
            configMessage.put("timestamp", System.currentTimeMillis());
            
            String topic = "device/" + imei + "/config";
            mqttService.sendToTopic(topic, JSON.toJSONString(configMessage));
            
            log.info("Config update sent to device: {}", imei);
            
        } catch (Exception e) {
            log.error("Error handling config update for device: {}", imei, e);
        }
    }
    
    /**
     * 处理OTA更新
     */
    private void handleOtaUpdate(String imei, JSONObject data) {
        try {
            Map<String, Object> otaMessage = new HashMap<>();
            otaMessage.put("type", "ota");
            otaMessage.put("url", data.getString("url"));
            otaMessage.put("version", data.getString("version"));
            otaMessage.put("md5", data.getString("md5"));
            otaMessage.put("size", data.getLong("size"));
            otaMessage.put("forceUpdate", data.getBooleanValue("forceUpdate"));
            otaMessage.put("timestamp", System.currentTimeMillis());
            
            String topic = "device/" + imei + "/ota";
            mqttService.sendToTopic(topic, JSON.toJSONString(otaMessage), 2, false);
            
            log.info("OTA update sent to device: {}, version: {}", imei, data.getString("version"));
            
        } catch (Exception e) {
            log.error("Error handling OTA update for device: {}", imei, e);
        }
    }
    
    /**
     * 处理定位请求
     */
    private void handleLocationRequest(String imei, JSONObject data) {
        try {
            Map<String, Object> locationRequest = new HashMap<>();
            locationRequest.put("type", "location_request");
            locationRequest.put("requestId", data.getString("requestId"));
            locationRequest.put("locationType", data.getString("locationType")); // GPS, LBS, WIFI
            locationRequest.put("timestamp", System.currentTimeMillis());
            
            String topic = "device/" + imei + "/request";
            mqttService.sendToTopic(topic, JSON.toJSONString(locationRequest));
            
            log.info("Location request sent to device: {}", imei);
            
        } catch (Exception e) {
            log.error("Error handling location request for device: {}", imei, e);
        }
    }
    
    /**
     * 处理设备控制
     */
    private void handleDeviceControl(String imei, JSONObject data) {
        try {
            String action = data.getString("action");
            
            Map<String, Object> controlMessage = new HashMap<>();
            controlMessage.put("type", "control");
            controlMessage.put("action", action);
            controlMessage.put("params", data.getJSONObject("params"));
            controlMessage.put("timestamp", System.currentTimeMillis());
            
            String topic = "device/" + imei + "/control";
            mqttService.sendToTopic(topic, JSON.toJSONString(controlMessage));
            
            log.info("Control command {} sent to device: {}", action, imei);
            
        } catch (Exception e) {
            log.error("Error handling device control for device: {}", imei, e);
        }
    }
    
    /**
     * 处理批量命令
     */
    private void handleBatchCommand(String imei, JSONObject data) {
        try {
            JSONArray commands = data.getJSONArray("commands");
            for (int i = 0; i < commands.size(); i++) {
                JSONObject cmd = commands.getJSONObject(i);
                processCommand(imei, cmd);
                // 添加延迟避免消息风暴
                Thread.sleep(100);
            }
            
            log.info("Batch commands processed for device: {}", imei);
            
        } catch (Exception e) {
            log.error("Error handling batch command for device: {}", imei, e);
        }
    }
    
    /**
     * 处理通用命令
     */
    private void handleGenericCommand(String imei, String command, JSONObject data) {
        try {
            Map<String, Object> genericMessage = new HashMap<>();
            genericMessage.put("command", command);
            genericMessage.put("data", data);
            genericMessage.put("timestamp", System.currentTimeMillis());
            
            String topic = "device/" + imei + "/data";
            mqttService.sendToTopic(topic, JSON.toJSONString(genericMessage));
            
            log.debug("Generic command {} sent to device: {}", command, imei);
            
        } catch (Exception e) {
            log.error("Error handling generic command for device: {}", imei, e);
        }
    }
    
    /**
     * 缓存离线消息
     */
    private void cacheOfflineMessage(String imei, JSONObject message) {
        // TODO: 实现离线消息缓存，可以存储到Redis
        log.info("Caching offline message for device: {}", imei);
    }
    
    /**
     * 发送确认消息到API服务
     */
    private void sendAckToApi(String imei, String msgId, boolean success, String message) {
        // TODO: 实现发送确认消息到API服务的逻辑
        log.debug("Sending ack to API - device: {}, msgId: {}, success: {}", imei, msgId, success);
    }
}